package xing.application.service.page;

import com.querydsl.core.Tuple;
import com.querydsl.core.group.Group;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAUpdateClause;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xing.application.service.BaseService;
import xing.application.service.page.dto.ModuleSort;
import xing.application.service.page.dto.ReplaceModuleInput;
import xing.domain.page.*;
import xing.domain.page.dto.ModuleItemDto;
import xing.domain.page.dto.ModuleList;
import xing.infrastructure.data.CallResult;
import xing.infrastructure.util.IdWorker;
import xing.repository.page.PageModuleRepository;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.querydsl.core.group.GroupBy.groupBy;
import static com.querydsl.core.group.GroupBy.list;
import static com.querydsl.core.group.GroupBy.set;

/********************************
 * 文 件 名 :ModuleService.java
 * 创 建 人：陈天龙
 * 日    期：2017/8/8
 * 描   述：模块业务处理类
 * 版 本 号：v1.0.0
 ********************************/
@Service
@CacheConfig(cacheNames = "module")
public class ModuleService extends BaseService {

    @Autowired
    PageModuleRepository moduleRepository;

    @Autowired
    EntityManagerFactory emf;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
    * @Description: 模块重新排序
    * @param:  * @moduleSorts
    * @Author: dustin
    * @Date: 2017-8-25
    */
    @Transactional
    public CallResult updateSort(List<ModuleSort> moduleSorts){
        QPageModule qModule=QPageModule.pageModule;
        for(ModuleSort ms:moduleSorts){
            //entityManager.merge(new PageModule(entry.getKey(),entry.getValue()));
            queryFactory.update(qModule).where(qModule.id.longValue().eq(ms.getId()))
                    .set(qModule.sort,ms.getSort())
                    .execute();
        }
        //entityManager.flush();

        return CallResult.ok();
    }
    /**
    * @Description: 删除模块及内容
    * @param:  * @moduleId
    * @Author: dustin
    * @Date: 2017-8-25
    */
    @Transactional
    public CallResult deleteModule(long moduleId,String corpId){
        QPageModule qModule=QPageModule.pageModule;
        QPageModuleItem qModuleItem=QPageModuleItem.pageModuleItem;
        long i=
        queryFactory.delete(qModuleItem)
                .where(qModuleItem.moduleid.longValue().eq(moduleId).and(qModuleItem.companycode.eq(corpId)))
                .execute();
        long j=
        queryFactory.delete(qModule)
                .where(qModule.id.longValue().eq(moduleId).and(qModule.companycode.eq(corpId)))
                .execute();

        return CallResult.ok();
    }

    /**
     * 描   述：新增模块
     * 创 建 人：陈天龙
     * 日    期：2017/8/8
     * @return CallResult
     */
    @Transactional
    public CallResult createModule(PageModule pageModule){
        logger.info("准备创建模板"+pageModule.getTemplateid()+"下的模块");
        //修改排序
        QPageModule qPageModule=QPageModule.pageModule;
        queryFactory.update(qPageModule)
                .set(qPageModule.sort,  qPageModule.sort.longValue().add(1))
                .where(qPageModule.templateid.eq(pageModule.getTemplateid())
                        .and(qPageModule.sort.goe(pageModule.getSort())))
                .execute();

        pageModule.setId(IdWorker.nextId());
        pageModule.setCreated(new Timestamp(System.currentTimeMillis()));
        moduleRepository.save(pageModule);

        logger.info("创建模块成功");
        return CallResult.ok();
    }
    /**
    * @Description: 获取模块列表
    * @param:  * @param null
    * @Author: dustin
    * @Date: 2017-8-15
    */
    public List<ModuleList> getSummeryList(String type,String companycode){
        List<ModuleList> list=moduleRepository.getSummeryList(type,companycode);
        return list;
    }

    /**
    * @Description: 更换模块
    * @param:  * @input
    * @Author: dustin
    * @Date: 2017-8-25
    */
    @Transactional
    public CallResult replaceModule(ReplaceModuleInput input){
        QPageModule qModule=QPageModule.pageModule;

        queryFactory.update(qModule).where(qModule.id.longValue().eq(input.getId()))
                //.set(qModule.name,input.getName())
                .set(qModule.showtype,input.getShowtype())
                .set(qModule.padding,input.getPadding())
                .set(qModule.backcolor,input.getBackcolor())
                .set(qModule.titleisshow,input.getTitleisshow())
                .set(qModule.titlecolor,input.getTitlecolor())
                .set(qModule.backcolor,input.getTitlebackcolor())
                .set(qModule.version,input.getVersion())
                .execute();

        return CallResult.ok();
    }
    /**
    * @Description: 以单模块为单位，导入模块内容 第一版不用
    * @param:  * @param null
    * @Author: dustin
    * @Date: 2017-8-28
    */
    public CallResult importModuleContent(long sourceModuleId,long targetModuleId,String corpId) {
        QPageModule qModule = QPageModule.pageModule;
        QPageModuleItem qPageModuleItem = QPageModuleItem.pageModuleItem;
        //取目标模块 公司code、最大排序值
        Long maxSort =
                queryFactory.select(qPageModuleItem.sort.max())
                        .from(qPageModuleItem)
                        .groupBy(qPageModuleItem.moduleid)
                        .where(qPageModuleItem.moduleid.eq(targetModuleId))
                        .fetchOne();

        if(maxSort==null){
            maxSort=0L;
        }

        //取源模块数据
        List<Tuple> sourceModule =
                queryFactory.select(qPageModuleItem.contentid,qPageModuleItem.reftype).from(qPageModuleItem)
                        .where(qPageModuleItem.moduleid.eq(sourceModuleId))
                        .fetch();
        if(sourceModule==null || sourceModule.size()==0) return CallResult.error("导入数据为空！");

        //导入到目标模块
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = null;
        Timestamp now = new Timestamp(System.currentTimeMillis());
        try {
            transaction = em.getTransaction();
            transaction.begin();
            for (Tuple t : sourceModule) {
                em.persist(new PageModuleItem(IdWorker.nextId(), targetModuleId, t.get(qPageModuleItem.contentid),t.get(qPageModuleItem.reftype) , ++maxSort, corpId, now));
            }
            em.flush();
            em.clear();
            transaction.commit();

            return CallResult.ok();
        } catch (RuntimeException e) {
            if (transaction != null &&
                    transaction.isActive()) {
                transaction.rollback();
            }
            throw e;
        } finally {
            if (em != null) {
                em.close();
            }
        }

    }

    public PageModule getModuleDetail1(long moduleId){
        QPageModule qModule=QPageModule.pageModule;
        QPageModuleItem qModuleItem=QPageModuleItem.pageModuleItem;
        QPageContentItem qContentItem=QPageContentItem.pageContentItem;

        Map<Long,PageModule> items=queryFactory
                .from(qModule,qModuleItem,qContentItem)
                .where(qModule.id.eq(moduleId).and(qModuleItem.moduleid.eq(qModule.id))
                        .and(qModuleItem.contentid.eq(qContentItem.id)))
                .orderBy(qModuleItem.sort.asc())
                .transform(groupBy(qModule.id)
                        .as(Projections.bean(PageModule.class,qModule.id,qModule.templateid,qModule.name,qModule.type,
                                qModule.level,qModule.showtype,qModule.sort,qModule.padding,qModule.backcolor,qModule.titleisshow,
                                qModule.titlecolor,qModule.titlebackcolor,qModule.companycode,qModule.version,qModule.created,
                                list(Projections.fields(ModuleItemDto.class, qModuleItem.id,qModuleItem.contentid, qModuleItem.moduleid, qModuleItem.sort,
                                        qContentItem.title,qContentItem.imageurl,qContentItem.size,qContentItem.target,qContentItem.type)
                                ).as("moduleItems"))))
                ;
        PageModule pageModule=null;
        if(items!=null && items.size()>0)
            pageModule = items.get(moduleId);

        return pageModule;
    }
    /**
    * @Description: 获取模块详细信息
    * @param:  * @param null
    * @Author: dustin
    * @Date: 2017-8-25
    */
    public CallResult getModuleDetail(long moduleId){

        PageModule module=moduleRepository.getModuleDetail(moduleId);
        if(null==module) return CallResult.error("不存在的模块");
        return CallResult.ok(module);
    }
    /**
    * @Description: 重命名
    * @param:  * @param null
    * @Author: dustin
    * @Date: 2017-8-25
    */
    @Transactional
    public CallResult updateModuleName(long moduleId,String name){
        QPageModule qPageModule=QPageModule.pageModule;
        long i=
                queryFactory.update(qPageModule).where(qPageModule.id.longValue().eq(moduleId))
                        .set(qPageModule.name,name)
                        .execute();
        return CallResult.code((int)i);
    }

}
